/*
  typescript是JS的超集， 也就是JS有的功能TS都有，主要还增加了类型系统，有了类型系统可以让我们
    更加好的开发一些大型的项目  ，  可以提前的就预知一些有可能发生的错误
  
  如果有强类型语言的基础话理解typescript是非常简单的  就和C# JAVA是非常非常像的语言
    ts 就是和强类型语言是一个道理的  但是TS在运行的时候任然也是需要先转换成JS，才能在
      乱来娶你和node.js中运行

  ts 的数据类型
    布尔类型
    数字类型
    字符串类型
    数组类型
    元祖类型
    枚举类型
    任意类型
    null 和 undefined类型
    void类型
    never类型
*/

/*
  布尔类型
*/
let flag: boolean = true
flag = false
//  flag = 12  会报错 因为类型已经定义的情况 就不能修改类型
console.log(flag)

// 数字类型
let age: number = 18
age = 20
console.log(age)

// 字符串类型
let names: string = 'Jimmy'
names = 'xuexue'
console.log(names)

// 数组类型
// 以下是正常的数组类型的使用 和 C#的是一样的
let arr: number[] = [1, 85, 7, 96, 12, 54]
arr.push(542)
console.log(arr)
// 泛型类型的使用  -- 类似于C# 泛型 的使用类型  也可以当做数组的类型来使用
let arr1: Array<string> = ['JImmy', 'xuexue', 'maomao']
console.log(arr1)

// 元祖类型
//  数组是只能存一种类型的数据 元祖可以理解成是可以存储多种数据类型的数组
let arr2: [string, number, boolean] = ['Jimmy', 20, true]
console.log(arr2)

// 枚举类型
enum pay_status {
  '未支付' = 0,
  '已支付' = 1,
  '交易成功' = 2,
}
let myStatus: pay_status = pay_status.已支付
console.log(myStatus) // 1

enum color {
  red,
  blue = 5,
  orange,
}
/*
  枚举类型 默认的索引都是从0开始的  如果从中间有跳过定义的话 后面也是+1的形式出现 
    前面是不会影响的
*/

let c0: color = color.red // 0
let c1: color = color.blue // 5
let c2: color = color.orange // 6
console.log(c0, c1, c2)

/*
  任意类型  any  --  可以任意的设置类型 就很像js  没有类型限制
*/
let tag: any = 15
tag = 19
tag = [16, 'haha', false]
console.log(tag) // [ 16, 'haha', false ]  可以看到我们随意的设置类型 ts也不会给我们报错

/*
  null 和 undefined类型
    只有在设置了他们值分别为 null 和 undefined的时候才不会报错 否则都会报错
*/
let num: null
num = null // 不报错
// num = 99   // 报错 只能是null 数据
let num1: undefined
num1 = undefined // 不报错

/*
  void 类型  ： 常常用于函数 表示的是当函数没有返回值的时候 那这个函数类型就是一个null类型
    xueguo c# 应该就是超级亲切的
*/
function show() {
  console.log('hello world')
}
show() // 不会报错  ES5的语法在TS里面是不会报错的
//  但是TS是一门严格的语言 最好没有返回值的时候我们就将函数定义为void类型就行
function show1(): void {
  console.log('i am ts void function~!')
}
show1() //  不会报错  反而是一个更加严谨的写法  这个和php很像

/*
  never类型  ：  是其他类型（包括null 和 undefined）的子类型，代表的是从来不会出现的值
*/
let a: never
// a = 15  报错  never类型是不能和其他类型一起使用的
//a = null

a = (() => {
  throw new Error('错误')
})() // 不报错
